package com.xjx.exception;

import com.xjx.enums.ErrorCode;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Data
@Slf4j
public class BusinessException extends RuntimeException {

    /**
     * 错误码
     */
    private final int code;

    /**
     * 错误信息
     * 这里不使用 message 作为变量名，以避免与父类 Throwable 的 getMessage() 混淆
     */
    private final String msg;

    /**
     * 主构造函数，用于业务逻辑中明确知道错误类型的情况
     *
     * @param errorCode 错误码枚举
     */
    public BusinessException(ErrorCode errorCode) {
        // 调用父类的构造函数，将错误信息传递过去
        super(errorCode.getMsg());
        this.code = errorCode.getCode();
        this.msg = errorCode.getMsg();
    }

    /**
     * 允许自定义错误信息的构造函数
     *
     * @param errorCode 错误码枚举
     * @param message   自定义的错误信息，会覆盖枚举中的默认信息
     */
    public BusinessException(ErrorCode errorCode, String message) {
        super(message);
        this.code = errorCode.getCode();
        this.msg = message;
    }

    /**
     * 包装（wrap）另一个异常的构造函数
     * 当捕获到一个底层异常（如 SQLException），并希望将其转换为业务异常时使用
     *
     * @param errorCode 错误码枚举
     * @param cause     原始异常
     */
    public BusinessException(ErrorCode errorCode, Throwable cause) {
        // 关键：将 cause 传递给父类，以保留原始异常的堆栈信息
        super(errorCode.getMsg(), cause);
        this.code = errorCode.getCode();
        this.msg = errorCode.getMsg();
    }

    /**
     * 最完整的构造函数，允许自定义信息并包装原始异常
     *
     * @param errorCode 错误码枚举
     * @param message   自定义错误信息
     * @param cause     原始异常
     */
    public BusinessException(ErrorCode errorCode, String message, Throwable cause) {
        super(message, cause);
        this.code = errorCode.getCode();
        this.msg = message;
    }

}
